using Dapper;
using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.WarehouseManagement;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Read.Api.Application.Command.ERP.PurchasingManagement.PurchaseReturns;
using RBAC.Read.Api.Application.Dto.ERP;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace RBAC.Read.Api.Application.Handler.ERP.PurchasingManagement.PurchaseReturns
{
    /// <summary>
    /// 采购退货单 与 物料 联查（分页）
    /// </summary>
    public class GetPurchaseReturnsWithMaterialsHandler : IRequestHandler<GetPurchaseReturnsWithMaterialsCommand, APIPaging<PurchaseReturnWithMaterialDto>>
    {
        private readonly IBaseRepository<PurchaseReturn> _repo;
        private readonly ILogger<GetPurchaseReturnsWithMaterialsHandler> _logger;

        public GetPurchaseReturnsWithMaterialsHandler(
            IBaseRepository<PurchaseReturn> repo,
            ILogger<GetPurchaseReturnsWithMaterialsHandler> logger)
        {
            _repo = repo;
            _logger = logger;
        }

        public Task<APIPaging<PurchaseReturnWithMaterialDto>> Handle(GetPurchaseReturnsWithMaterialsCommand request, CancellationToken cancellationToken)
        {
            var res = new APIPaging<PurchaseReturnWithMaterialDto>();
            try
            {
                // FROM：以物料明细为行
                var fromSql = @" FROM PurchaseReturn pr
                                   INNER JOIN PurchaseReturnMaterial prm ON prm.PurchaseReturnId = pr.Id AND prm.IsDel = 0
                                   WHERE pr.IsDeleted = 0";

                var whereParts = new List<string>();
                var param = new DynamicParameters();

                if (!string.IsNullOrWhiteSpace(request.DocumentCode))
                {
                    whereParts.Add("pr.DocumentCode LIKE @DocumentCode");
                    param.Add("DocumentCode", $"%{request.DocumentCode}%");
                }
                if (!string.IsNullOrWhiteSpace(request.OrderNumber))
                {
                    whereParts.Add("prm.OrderNumber LIKE @OrderNumber");
                    param.Add("OrderNumber", $"%{request.OrderNumber}%");
                }
                if (!string.IsNullOrWhiteSpace(request.MaterialCode))
                {
                    whereParts.Add("prm.MaterialCode LIKE @MaterialCode");
                    param.Add("MaterialCode", $"%{request.MaterialCode}%");
                }
                if (!string.IsNullOrWhiteSpace(request.MaterialName))
                {
                    whereParts.Add("prm.MaterialName LIKE @MaterialName");
                    param.Add("MaterialName", $"%{request.MaterialName}%");
                }

                var whereSql = whereParts.Count > 0 ? (" AND " + string.Join(" AND ", whereParts)) : string.Empty;

                // 1) 统计总数（以明细行为单位）
                var countSql = "SELECT COUNT(1)" + fromSql + whereSql;
                var total = _repo.Query<int>(countSql, param).FirstOrDefault();

                res.TotalCount = total;
                res.Code = APIEnums.Success;
                res.Msg = "获取采购退货单联查成功";

                if (total == 0)
                {
                    res.PageDatas = new List<PurchaseReturnWithMaterialDto>();
                    return Task.FromResult(res);
                }

                // 2) 分页查询
                var pageIndex = request.PageIndex <= 0 ? 1 : request.PageIndex;
                var pageSize = request.PageSize <= 0 ? 10 : request.PageSize;
                var offset = (pageIndex - 1) * pageSize;
                if (offset < 0) offset = 0;
                param.Add("Offset", offset);
                param.Add("PageSize", pageSize);

                var dataSql = @"SELECT 
                                    pr.Id AS PurchaseReturnId,
                                    pr.DocumentCode,
                                    pr.DocumentStatus,
                                    pr.DocumentDate,
                                    pr.BusinessType,
                                    pr.BusinessStatus,
                                    pr.PurchaseOrderNumber,
                                    pr.Operator,
                                    pr.SupplierId,
                                    pr.Auditor,
                                    pr.ReturnWarehouse,
                                    pr.ReviewDate,
                                    pr.ReasonReturn,
                                    pr.RemarkInformation,
                                    prm.PurchaseReturnMaterialId,
                                    prm.OrderNumber,
                                    prm.MaterialCode,
                                    prm.MaterialName,
                                    prm.ModelSpecifications,
                                    prm.MainMeasurement,
                                    prm.BatchNumber,
                                    prm.Number,
                                    prm.OutboundQuantity,
                                    prm.ReturnInstructions
                                " + fromSql + whereSql + @"
                                ORDER BY pr.Id DESC, prm.PurchaseReturnMaterialId DESC
                                LIMIT @Offset, @PageSize";

                var rows = _repo.Query<PurchaseReturnWithMaterialDto>(dataSql, param).ToList();
                res.PageDatas = rows;
            }
            catch (System.Exception ex)
            {
                res.Code = APIEnums.Error;
                res.Msg = "获取采购退货单联查失败";
                _logger.LogError(ex, "获取采购退货单联查失败: {Message}", ex.Message);
            }

            return Task.FromResult(res);
        }
    }
}
